package com.example.shiro_demo1.shiro;

import com.example.shiro_demo1.pojo.Permission;
import com.example.shiro_demo1.pojo.Role;
import com.example.shiro_demo1.pojo.User;
import com.example.shiro_demo1.service.UserService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * @author cxp
 * @version 1.0
 * @date 2019/6/27 10:13
 */
public class ShiroRealm extends AuthorizingRealm {
    @Autowired
    private UserService userService;

    /**
     * 该方法为Shiro的核心，在执行过登录操作之后会调用该方法，只要为识别当前Subject的用户是否拥有当前访问请求的权限
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        principalCollection.fromRealm(this.getClass().getName()).forEach(e->{
            System.out.println(e.toString());
        });
        User user = (User) principalCollection.fromRealm(this.getClass().getName()).iterator().next();
        List<String> permissionList = new ArrayList<>();
        List<String> roleList = new ArrayList<>();
        Set<Role> roles = user.getRoles();
        if (CollectionUtils.isNotEmpty(roles)){
            for (Role role:roles) {
                roleList.add(role.getRname());
                Set<Permission> permissions = role.getPermissions();
                if (CollectionUtils.isNotEmpty(permissions)){
                    for (Permission permission:permissions) {
                        //可以将权限类的url添加进去，在这只添加权限名称
                        permissionList.add(permission.getName());
                    }
                }
            }
        }
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        info.addRoles(roleList);
        info.addStringPermissions(permissionList);
        return info;
    }

    /**
     * 用户的登录认证的方法
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("将用户，密码填充完UsernamePasswordToken之后，进行subject.login(token)之后");
        //这边是界面的登陆数据，将数据封装成token
        UsernamePasswordToken userpasswordToken = (UsernamePasswordToken) authenticationToken;
        String username = userpasswordToken.getUsername();
        User user = userService.findByUsername(username);
        SimpleAuthenticationInfo info = null;
        if (null!=user){
            info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getClass().getName());
            info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
        }else{
            throw new UnknownAccountException("用户不存在");
        }
        return info;
    }
}
